#ifndef TIEC_DATA_H
#define TIEC_DATA_H

#include <algorithm>
#include <shared_mutex>
#include <vector>
#include <unordered_map>
#include <stack>
#include <unordered_set>
#include <queue>
#include <deque>
#include <iterator>

#include "macro.h"

namespace NS_TIEC {
  
  struct NullValue {};
  static NullValue kGlobalNullValue = NullValue();

  /// 字节集定义
  struct ByteArray {
    char* data;
    UInt64 length;

    static ByteArray kEmpty;
  };

  /// Uri实现
  class Uri {
  public:
    static Uri kEmpty;

    /// 解析字符串uri得到uri对象
    /// \param uri_string 字符串Uri
    /// \return Uri对象
    static Uri fromString(const String& uri_string);

    /// 获取Uri的协议
    /// \return 协议名称
    String getScheme();

    /// 获取Uri的host:port
    /// \return host:port
    String getAuthority();

    /// 获取Uri的资源路径
    /// \return path
    String& getPath();

    /// 获取Uri的资源路径
    /// \return path
    const String getPath() const;

    /// 获取Uri的资源路径（C字符串形式）
    /// @return path c data
    const char* getPathData() const;

    /// 获取Uri的query部分
    /// \return query值
    String getQuery();

    /// 获取Uri的fragment部分
    /// \return #...
    String getFragment();

    /// Uri转换为String
    /// \return Uri字符串`
    String asString() const;

    /// 计算Uri的哈希值
    size_t hash() const;

    const bool operator==(const Uri& other) const;
  private:
    String scheme_;
    String authority_;
    String path_;
    String query_;
    String fragment_;
  };

  /// Uri的hash计算函数
  struct UriHash {
    const size_t operator()(const Uri& uri) const {
      return uri.hash();
    }
  };
  /// Uri的值比对函数
  struct UriEqual {
    const size_t operator()(const Uri& a, const Uri& b) const {
      return a == b;
    }
  };

  /// 列表数据结构
  template<typename T>
  class List {
  public:
    List() = default;

    List(const List<T>& other) {
      vector_ = other.vector_;
    }

    List(const List<T>&& other) noexcept {
      vector_ = std::move(other.vector_);
    }

    List& operator=(const List<T>& other) {
      if (this != &other) {
        vector_ = other.vector_;
      }
      return *this;
    }

    List& operator=(const List<T>&& other) noexcept {
      vector_ = std::move(other.vector_);
      return *this;
    }

    template <typename... Elements>
    static List<T> of(Elements&&... elements) {
      List<T> result;
      (result.add(std::forward<Elements>(elements)), ...);
      return result;
    }

    T& at(const size_t index) {
      return vector_.at(index);
    }

    const T& at(const size_t index) const {
      return vector_.at(index);
    }

    T& operator[](const size_t index) {
      return vector_[index];
    }

    const T& operator[](const size_t index) const {
      return vector_[index];
    }

    template<typename U>
    void add(U&& element) {
      vector_.push_back(std::forward<U>(element));
    }

    void addAll(const List<T>& other) {
      other.forEach([this](const T& element) {
        vector_.push_back(element);
      });
    }

    template<typename U>
    void set(size_t index, U&& element) {
      if (index > vector_.size()) return;
      vector_[index] = std::forward<U>(element);
    }

    template<typename U>
    bool insert(size_t index, U&& element) {
      if (index > vector_.size()) return false;
      vector_.insert(vector_.begin() + index, std::forward<U>(element));
      return true;
    }

    bool insertAll(size_t index, const List<T>& other) {
      if (index > vector_.size()) return false;
      vector_.insert(vector_.begin() + index, other.begin(), other.end());
      return true;
    }

    template<typename U>
    bool remove(U&& element) {
      auto it = std::find(vector_.begin(), vector_.end(), std::forward<U>(element));
      if (it != vector_.end()) {
        vector_.erase(it);
        return true;
      }
      return false;
    }

    bool removeAt(int index) {
      if (index > vector_.size()) return false;
      vector_.erase(vector_.begin() + index);
      return true;
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, T&>>>
    void removeFirst(Func&& predicate) {
      auto it = std::find_if(vector_.begin(), vector_.end(), predicate);
      if (it != vector_.end()) {
        vector_.erase(it);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, T&>>>
    List<T> removeAll(Func&& predicate) {
      List<T> removed;
      for (auto it = vector_.begin(); it != vector_.end(); ) {
        if (std::forward<Func>(predicate)(*it)) {
          removed.add(*it);
          it = vector_.erase(it);
        } else {
          ++it;
        }
      }
      return removed;
    }

    T first() {
      if (vector_.empty()) {
        return {};
      }
      return vector_.front();
    }

    const T first() const {
      if (vector_.empty()) {
        return {};
      }
      return vector_.front();
    }

    T last() {
      if (vector_.empty()) {
        return {};
      }
      return vector_.back();
    }

    const T last() const {
      if (vector_.empty()) {
        return {};
      }
      return vector_.back();
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const T&>>>
    void forEach(Func&& consumer) const {
      for (const auto& item : vector_) {
        std::forward<Func>(consumer)(item);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, T&>>>
    void forEach(Func&& consumer) {
      for (auto& item : vector_) {
        std::forward<Func>(consumer)(item);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, T&>>>
    void forEachUntil(Func&& consumer) {
      for (auto& item : vector_) {
        if (std::forward<Func>(consumer)(item)) {
          return;
        }
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, const T&>>>
    T findFirst(Func&& filter) {
      auto it =  std::find_if(vector_.begin(), vector_.end(), filter);
      if (it != vector_.end()) {
        return *it;
      }
      return {};
    }

    template<typename U>
    bool contains(U&& element) {
      return std::find(vector_.begin(), vector_.end(), std::forward<U>(element)) != vector_.end();
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, const T&>>>
    bool containsIf(Func&& filter) const {
      return std::any_of(vector_.begin(), vector_.end(), filter);
    }

    template<typename U, typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, U, const T&>>>
    List<U> transform(Func&& transformer) const {
      List<U> result;
      for (const auto& item : vector_) {
        result.add(std::forward<Func>(transformer)(item));
      }
      return result;
    }

    void clear() {
      vector_.clear();
    }

    bool empty() const {
      return vector_.empty();
    }

    size_t size() const {
      return vector_.size();
    }

    List<T> subList(const size_t start, const size_t count) {
      if (start + count > vector_.size()) {
        throw std::out_of_range("subList: out of range [0, " + size() + ")");
      }
      List<T> result;
      for (size_t i = start; i < start + count; i++) {
        result.add(vector_[i]);
      }
      return result;
    }

    typename std::vector<T>::iterator begin() {
      return vector_.begin();
    }

    typename std::vector<T>::iterator end() {
      return vector_.end();
    }

    typename std::vector<T>::const_iterator begin() const {
      return vector_.begin();
    }

    typename std::vector<T>::const_iterator end() const {
      return vector_.end();
    }
  private:
    std::vector<T> vector_;
  };

  /// 哈希表数据结构
  template<typename K, typename V, typename Hash = std::hash<K>, typename KeyEqual = std::equal_to<K>>
  class HashMap {
  public:
    HashMap() = default;

    HashMap(const HashMap<K, V, Hash, KeyEqual>& other) {
      map_ = other.map_;
    }

    HashMap(HashMap<K, V, Hash, KeyEqual>&& other) noexcept {
      map_ = std::move(other.map_);
    }

    HashMap<K, V, Hash, KeyEqual>& operator=(const HashMap<K, V, Hash, KeyEqual>& other) {
      if (this != &other) {
        map_ = other.map_;
      }
      return *this;
    }

    HashMap<K, V, Hash, KeyEqual>& operator=(HashMap<K, V, Hash, KeyEqual>&& other) noexcept {
      map_ = std::move(other.map_);
      return *this;
    }

    V& get(const K& key) {
      return map_.at(key);
    }

    const V& get(const K& key) const {
      return map_.at(key);
    }

    V& operator[](const K& key) {
      return map_.at(key);
    }

    const V& operator[](const K& key) const {
      return map_.at(key);
    }

    template<typename KType, typename VType>
    void put(KType&& key, VType&& value) {
      map_.insert_or_assign(std::forward<KType>(key), std::forward<VType>(value));
    }

    void putAll(const HashMap<K, V, Hash, KeyEqual>& other) {
      for (const PAIR<K, V>& pair : other) {
        map_.insert_or_assign(pair.first, pair.second);
      }
    }

    V& getOrDefault(const K& key, V& def_value) {
      auto it = map_.find(key);
      if (it != map_.end()) {
        return it->second;
      }
      return def_value;
    }

    V getOrDefault(const K& key, const V& def_value) const {
      auto it = map_.find(key);
      if (it != map_.end()) {
        return it->second;
      }
      return def_value;
    }

    bool contains(const K& key) const {
      return map_.find(key) != map_.end();
    }

    bool remove(const K& key) {
      return map_.erase(key) > 0;
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, const K&, const V&>>>
    void removeAll(Func&& predicate) {
      for (auto it = map_.begin(); it != map_.end(); ) {
        if (std::forward<Func>(predicate)((*it).first, (*it).second)) {
          it = map_.erase(it);
        } else {
          ++it;
        }
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const K&, const V&>>>
    void forEach(Func&& consumer) const {
      for (const auto& [key, value] : map_) {
        std::forward<Func>(consumer)(key, value);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const K&, V&>>>
    void forEach(Func&& consumer) {
      for (auto& [key, value] : map_) {
        std::forward<Func>(consumer)(key, value);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, const K&, const V&>>>
    void forEachUntil(Func&& consumer) {
      for (auto& [key, value] : map_) {
        if (std::forward<Func>(consumer)(key, value)) {
          return;
        }
      }
    }

    List<K> keys() const {
      List<K> keyList;
      for (const auto& [key, value] : map_) {
        keyList.add(key);
      }
      return keyList;
    }

    List<V> values() const {
      List<V> valueList;
      for (const auto& [key, value] : map_) {
        valueList.add(value);
      }
      return valueList;
    }

    bool empty() const {
      return map_.empty();
    }

    size_t size() const {
      return map_.size();
    }

    void clear() {
      map_.clear();
    }

    typename std::unordered_map<K, V, Hash, KeyEqual>::iterator begin() {
      return map_.begin();
    }

    typename std::unordered_map<K, V, Hash, KeyEqual>::iterator end() {
      return map_.end();
    }

    typename std::unordered_map<K, V, Hash, KeyEqual>::const_iterator begin() const {
      return map_.begin();
    }

    typename std::unordered_map<K, V, Hash, KeyEqual>::const_iterator end() const {
      return map_.end();
    }

  private:
    std::unordered_map<K, V, Hash, KeyEqual> map_;
  };

  /// 集合数据结构
  template<typename T, typename Hash = std::hash<T>, typename KeyEqual = std::equal_to<T>>
  class Set {
  public:
    Set() = default;

    Set(const Set<T, Hash, KeyEqual>& other) {
      set_ = other.set_;
    }

    Set(Set<T, Hash, KeyEqual>&& other) noexcept {
      set_ = std::move(other.set_);
    }

    Set& operator=(const Set<T, Hash, KeyEqual>& other) {
      if (this != &other) {
        set_ = other.set_;
      }
      return *this;
    }

    Set& operator=(Set<T, Hash, KeyEqual>&& other) noexcept {
      set_ = std::move(other.set_);
      return *this;
    }

    template<typename U>
    void add(U&& element) {
      set_.emplace(std::forward<U>(element));
    }

    void addAll(const Set<T, Hash, KeyEqual>& other) {
      for (const T& element : other) {
        set_.emplace(element);
      }
    }

    template<typename U>
    bool remove(U&& element) {
      auto it = std::find(set_.begin(), set_.end(), std::forward<U>(element));
      if (it != set_.end()) {
        set_.erase(it);
        return true;
      }
      return false;
    }

    bool has(const T& element) {
      return std::find(set_.begin(), set_.end(), element) != set_.end();
    }

    const bool has(const T& element) const {
      return std::find(set_.begin(), set_.end(), element) != set_.end();
    }

    size_t size() const {
      return set_.size();
    }

    bool empty() const {
      return set_.empty();
    }

    T findFirst(FUNCTION<bool(const T&)> filter) {
      for (const auto& item : set_) {
        if (filter(item)) {
          return item;
        }
      }
      return {};
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const T&>>>
    void forEach(Func&& consumer) const {
      for (const auto& item : set_) {
        std::forward<Func>(consumer)(item);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, const T&>>>
    void forEachUntil(Func&& consumer) {
      for (auto& item : set_) {
        if (std::forward<Func>(consumer)(item)) {
          return;
        }
      }
    }

    typename std::unordered_set<T, Hash, KeyEqual>::iterator begin() {
      return set_.begin();
    }

    typename std::unordered_set<T, Hash, KeyEqual>::iterator end() {
      return set_.end();
    }

    typename std::unordered_set<T, Hash, KeyEqual>::const_iterator begin() const {
      return set_.begin();
    }

    typename std::unordered_set<T, Hash, KeyEqual>::const_iterator end() const {
      return set_.end();
    }
  private:
    std::unordered_set<T, Hash, KeyEqual> set_;
  };

  /// 栈数据结构
  template<typename T>
  class Stack {
  public:
    Stack() = default;

    Stack(const Stack<T>& other) {
      stack_ = other.stack_;
    }

    Stack(Stack<T>&& other) noexcept {
      stack_ = std::move(other.stack_);
    }

    Stack& operator=(const Stack<T>& other) {
      if (this != &other) {
        stack_ = other.stack_;
      }
      return *this;
    }

    Stack& operator=(Stack<T>&& other) noexcept {
      stack_ = std::move(other.stack_);
      return *this;
    }

    template<typename U>
    void push(U&& value) {
      stack_.push(std::forward<U>(value));
    }

    T& pop() {
      T& top = stack_.top();
      stack_.pop();
      return top;
    }

    const T& pop() const {
      T& top = stack_.top();
      stack_.pop();
      return top;
    }

    T& top() {
      return stack_.top();
    }

    const T& top() const {
      return stack_.top();
    }

    size_t size() const {
      return stack_.size();
    }

    void clear() {
      stack_.clear();
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const T&>>>
    void forEach(Func&& consumer) const {
      for (const auto& value : stack_) {
        std::forward<Func>(consumer)(value);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, T&>>>
    void forEach(Func&& consumer) {
      for (auto& value : stack_) {
        std::forward<Func>(consumer)(value);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, const T&>>>
    bool containsIf(Func&& consumer) {
      return std::any_of(stack_.begin(), stack_.end(), consumer);
    }
  private:
    std::stack<T> stack_;
  };

  /// 队列数据结构
  template<typename T>
  class Queue {
  public:
    Queue() = default;

    Queue(const Queue<T>& other) {
      queue_ = other.queue_;
    }

    Queue(Queue<T>&& other) noexcept {
      queue_ = std::move(other.queue_);
    }

    Queue& operator=(const Queue<T>& other) {
      if (this != &other) {
        queue_ = other.queue_;
      }
      return *this;
    }

    Queue& operator=(Queue<T>&& other) noexcept {
      queue_ = std::move(other.queue_);
      return *this;
    }

    template<typename U>
    void enqueue(U&& value) {
      queue_.push(std::forward<U>(value));
    }

    bool dequeue(T& value) {
      if (queue_.empty()) {
        return false;
      }
      value = std::move(queue_.front());
      queue_.pop();
      return true;
    }

    T tryDequeue() {
      if (queue_.empty()) {
        return T{};
      }
      T value = std::move(queue_.front());
      queue_.pop();
      return value;
    }

    bool peek(T& value) const {
      if (queue_.empty()) {
        return false;
      }
      value = queue_.front();
      return true;
    }

    T front() const {
      if (queue_.empty()) {
        return T{};
      }
      return queue_.front();
    }

    T back() const {
      if (queue_.empty()) {
        return T{};
      }
      return queue_.back();
    }

    bool empty() const {
      return queue_.empty();
    }

    size_t size() const {
      return queue_.size();
    }

    void clear() {
      while (!queue_.empty()) {
        queue_.pop();
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const T&>>>
    void forEach(Func&& consumer) const {
      std::queue<T> temp = queue_;
      while (!temp.empty()) {
        std::forward<Func>(consumer)(temp.front());
        temp.pop();
      }
    }
  private:
    std::queue<T> queue_;
  };

  /// 双端队列数据结构
  template<typename T>
  class Deque {
  public:
    Deque() = default;

    Deque(const Deque<T>& other) {
      deque_ = other.deque_;
    }

    Deque(Deque<T>&& other) noexcept {
      deque_ = std::move(other.deque_);
    }

    Deque& operator=(const Deque<T>& other) {
      if (this != &other) {
        deque_ = other.deque_;
      }
      return *this;
    }

    Deque& operator=(Deque<T>&& other) noexcept {
      deque_ = std::move(other.deque_);
      return *this;
    }

    template<typename U>
    void pushBack(U&& value) {
      deque_.push_back(std::forward<U>(value));
    }

    template<typename U>
    void pushFront(U&& value) {
      deque_.push_front(std::forward<U>(value));
    }

    bool popBack(T& value) {
      if (deque_.empty()) {
        return false;
      }
      value = std::move(deque_.back());
      deque_.pop_back();
      return true;
    }

    bool popFront(T& value) {
      if (deque_.empty()) {
        return false;
      }
      value = std::move(deque_.front());
      deque_.pop_front();
      return true;
    }

    T tryPopBack() {
      if (deque_.empty()) {
        return T{};
      }
      T value = std::move(deque_.back());
      deque_.pop_back();
      return value;
    }

    T tryPopFront() {
      if (deque_.empty()) {
        return T{};
      }
      T value = std::move(deque_.front());
      deque_.pop_front();
      return value;
    }

    T front() const {
      if (deque_.empty()) {
        return T{};
      }
      return deque_.front();
    }

    T back() const {
      if (deque_.empty()) {
        return T{};
      }
      return deque_.back();
    }

    T at(size_t index) const {
      if (index >= deque_.size()) {
        return T{};
      }
      return deque_.at(index);
    }

    template<typename U>
    bool insert(size_t index, U&& value) {
      if (index > deque_.size()) {
        return false;
      }
      deque_.insert(deque_.begin() + index, std::forward<U>(value));
      return true;
    }

    bool erase(size_t index) {
      if (index >= deque_.size()) {
        return false;
      }
      deque_.erase(deque_.begin() + index);
      return true;
    }

    bool empty() const {
      return deque_.empty();
    }

    size_t size() const {
      return deque_.size();
    }

    void clear() {
      deque_.clear();
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const T&>>>
    void forEach(Func&& consumer) const {
      for (const auto& item : deque_) {
        std::forward<Func>(consumer)(item);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, T&>>>
    void forEach(Func&& consumer) {
      for (auto& item : deque_) {
        std::forward<Func>(consumer)(item);
      }
    }

    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, const T&>>>
    T findFirst(Func&& filter) const {
      auto it = std::find_if(deque_.begin(), deque_.end(), filter);
      if (it != deque_.end()) {
        return *it;
      }
      return T{};
    }

    template<typename U>
    bool contains(U&& element) const {
      return std::find(deque_.begin(), deque_.end(), std::forward<U>(element)) != deque_.end();
    }

  private:
    std::deque<T> deque_;
  };

  /// 常量值类型
  enum struct ConstKind {
    Null = 0,
    Boolean,
    Int,
    Long,
    Float,
    Double,
    Char,
    String
  };
  /// 常量值值封装
  class ConstValue {
  public:
    static ConstValue kNull;

    ConstValue();
    ConstValue(const NullValue& v);
    ConstValue(const int32_t v);
    ConstValue(const int64_t v);
    ConstValue(const bool v);
    ConstValue(const float v);
    ConstValue(const double v);
    ConstValue(const String& v);
    ConstValue(const wchar_t v);
    ConstValue(String&& v);
    ConstValue(const ConstValue& other);
    ConstValue(ConstValue&& other) noexcept;
    ConstValue& operator=(const ConstValue& other);
    ConstValue& operator=(ConstValue&& other) noexcept;
    ~ConstValue();
    bool operator==(const ConstValue& other) const;
    bool operator!=(const ConstValue& other) const;

    bool isNull() const;

    bool isString() const;

    ConstKind getKind() const;

    String asString() const;

    template<typename T>
    T getAs() const {
      return *static_cast<T*>(value_);
    }

  private:
    void* value_;
    ConstKind kind_;

    void deepCopyFrom(const ConstValue& other);
    void destroy();
  };

} // NS_TIEC

#endif //TIEC_DATA_H
